#ifndef __IO__
#define __IO__

#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string>
#include <vector>

#include "hdf5.h"
#include "H5Cpp.h"
#include "H5File.h"

#include <qk.h>



typedef struct h5_chunked_file_info
{
	H5std_string name;

	hsize_t dset_dims[2];
	hsize_t chunk_dims[2];

	hid_t	  file_id;   /* file id */
	hid_t   dset_id;   /* data set id */
	hid_t   space_id;  /* data space id */
	hid_t   dcpl_id;   /* data creation property list id*/
};

typedef std::vector<h5_chunked_file_info> h5files_container;

namespace io
{
  // Input HDF5 file is read assuming matrices are stored as:
  //
  // EnergyBands(ik,ib1)  ,    kpoints(ik,icartesian)
  
  void read_input_hdf5_file(const char* filename,
			    arma::vec& time,
			    arma::vec& Efield,
			    arma::mat& kpoints,
			    arma::mat& EnergyBands,
			    complex_matrix_function& InteractionHamiltonian,
			    complex_matrix_function& rho0);

  void read_kpoints(const char* filename, arma::mat& kpoints, double& dkx, int& nx);
  void read_fields(const char* filename, arma::vec& time, arma::vec& Efield);
  void set_filenames(h5files_container& files);
  void disk_storage_initialization(
				   h5files_container& files,
				   const parameters& params);
  
  void dump(
	    const h5_chunked_file_info& file,  
	    const complex_matrix_function& M, 
	    const parameters& params,
	    const int t1_indexh5dump         // t1_indexh5dump is used to determine the 
	    // index for the 
	    // point where the blocks are added to each
	    // horizontal line
	    );
  
  void load(const h5_chunked_file_info& file,
	    const parameters& params,
	    const int itau,
	    complex_matrix_function& M);
  
}


#endif
